package com.joshua.spring.gateway.config;

import com.joshua.spring.gateway.constant.RedisConstants;
import com.joshua.spring.gateway.entity.dto.RouteDefinitionRefreshEvent;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.context.ApplicationEventPublisherAware;
import org.springframework.data.redis.connection.Message;
import org.springframework.data.redis.listener.KeyspaceEventMessageListener;
import org.springframework.data.redis.listener.PatternTopic;
import org.springframework.data.redis.listener.RedisMessageListenerContainer;
import org.springframework.util.ObjectUtils;

/**
 * projectName dragon-cloud
 * package com.joshua.spring.gateway.config
 * classname  RedisRouteMessageListener
 * <p>
 * description
 * </p>
 *
 * @author <a href="mailto:joshualwork@163.com">joshua_liu</a>
 * @date 2020/8/22 11:35
 */
@Slf4j
public class RemoteRouteMessageListener extends KeyspaceEventMessageListener implements ApplicationEventPublisherAware {

    private ApplicationEventPublisher eventPublisher;
    private int database;

    public RemoteRouteMessageListener(RedisMessageListenerContainer listenerContainer) {
        super(listenerContainer);
    }

    /**
     * __keyevent@*__:hset
     */
    @Override
    protected void doRegister(RedisMessageListenerContainer container) {
        String patternTopic = String.format(RedisConstants.Formatter.KEY_EVENT_FORMATTER,
                database, RedisConstants.H_SET);
        log.info("Listener pattern topic [{}]", patternTopic);
        container.addMessageListener(this, new PatternTopic(patternTopic));
    }


    @Override
    protected void doHandleMessage(Message message) {
        String redisKey = new String(message.getBody());
        String keyEvent = new String(message.getChannel());
        log.info("Receive redis message, [redisKey->{},keyEvent->{}]", redisKey, keyEvent);
        if (RedisConstants.GatewayKey.ROUTE_INFO_KEY.equals(redisKey)) {
            if (!ObjectUtils.isEmpty(eventPublisher)) {
                eventPublisher.publishEvent(new RouteDefinitionRefreshEvent());
                log.info("Start do handle message, [redisKey->{},keyEvent->{}]", redisKey, keyEvent);
            }
        }
    }

    @Override
    public void setApplicationEventPublisher(ApplicationEventPublisher applicationEventPublisher) {
        this.eventPublisher = applicationEventPublisher;
    }

    public void setDatabase(int database) {
        this.database = database;
    }
}
